<?
	/* Se asegura que el archivo es incluido por el index */
	// defined( 'LOAD_MODULE_ACTION' ) or die( 'No esta permitido el acceso directo a ' . __FILE__ );
	/* Cuando se hace el include del archivo automaticamente crea un objeto y lo guarda en una variable temporal */
		$this->oTmpObject = new Usuario_exe( $this );
	class Usuario_exe extends Exe
	{
	function Usuario_exe( &$oModule )
		{
			$this->Exe( $oModule );
		}
		function unlock()
		{
			$ncUsuario = getParam('ncUsuario');
			if ( $ncUsuario )
			{
				$this->oDatabase->update( 'stUsuario', "bBloqueada", 0, "WHERE", "ncUsuario", $ncUsuario );
			}
		}
		function lock()
		{
			$ncUsuario = getParam('ncUsuario');
			if ( $ncUsuario )
			{
				$this->oDatabase->update( 'stUsuario', "bBloqueada", 1, "WHERE", "ncUsuario", $ncUsuario );
			}
		}
		// MODIFICAR_UN_USUARIO
		function update()
			{
				// Convierte a variables los datos del Formulario asociado a la accion
				$oForm = $this->oModule->loadClass( 'Usuario_frm' );
				extract( $oForm->getFieldArray() );
				$aActores = $oForm->aFields['aActores']->getValue();
				$cModuleAnterior = $cRoles = "";
				foreach ( $aActores as $cActor )
				{
					list ( $cModule, $ncActor )  = explode( "|", $cActor);
					if ( $cModule != $cModuleAnterior )
					{
						$cRoles .= ";" . $cModule . ":$ncActor";
						$cModuleAnterior = $cModule;
					} else $cRoles .= ",$ncActor";
				}
				$cRoles = substr( $cRoles, 1) . ";";
				// Modifica el Registro de Usuario
					$this->oDatabase->update('stUsuario',
										'cUsuario', $cUsuario,
										"cEmail", $cEmail,
										"cRoles", $cRoles,
										"dModificacion", Date("Y-m-d") ,
									"WHERE",
									"ncUsuario", $ncUsuario );
				$this->setInputData( $ncUsuario, $cUsuario );
			}
		function add($cUsuario, $ncUsuario = '')
		{
			if ( $ncUsuario )
			{
				// Verifica que el codigo no exista
				$nqExiste = $this->oDatabase->getData("SELECT count(*) FROM stUsuario WHERE ncUsuario = '$ncUsuario'");
				if ( $nqExiste > 0 ) $ncUsuario = '';
			}
			if ( $ncUsuario == '' )
			{
				$ncUsuario = $this->oDatabase->nextKey( 'stUsuario', "ncUsuario" );
			}
			// Verifica que el nombre del usuario
			$nqExiste = $this->oDatabase->getData("SELECT count(*) FROM stUsuario  WHERE cUsuario  = '$cUsuario'");
			// Si existe agrega un indice
			for ( $nIndex = 1, $cUsuarioBase = $cUsuario; $nqExiste > 0; $nIndex++ )
			{
				$cUsuario = $cUsuarioBase . $nIndex;
				$nqExiste = $this->oDatabase->getData("SELECT count(*) FROM stUsuario WHERE cUsuario = '$cUsuario'");
			}
			// Arma el conjunto de roles de usuario de cada modulo (default)
				global $aInstallModules;
				$cRoles = '';
				foreach ( $aInstallModules as $cKey => $aInstallModule )
				{
					if ( $cKey != 'base' ) $cRoles .= $cKey .'=usuario;'; 
				}
			// Agrega el usuario
			$this->oDatabase->insert('stUsuario',
								"cEmail", $cEmail,
								'cUsuario', $cUsuario,
								"dAlta", Date("Y-m-d") ,
								"dModificacion", Date("Y-m-d") ,
								"cRoles", $cRoles,
								"bActivo", 1,
								"ncUsuario", $ncUsuario );
		}
		// AGREGAR_UN_USUARIO
		function insert()
			{
			// Arma el conjunto de roles de usuario de cada modulo (default)
				global $aInstallModules;
				$cRoles = '';
				foreach ( $aInstallModules as $cKey => $aInstallModule )
				{
					if ( $cKey != 'base' ) $cRoles .= $cKey .'=usuario;'; 
				}
				// Convierte a variables los datos del Formulario asociado a la accion
				$oForm = $this->oModule->loadClass( 'Usuario_frm' );
				extract( $oForm->getFieldArray() );
				// Agrega la Usuario
					$ncUsuario = $this->oDatabase->nextKey('stUsuario', "ncUsuario" );
					$this->oDatabase->insert('stUsuario',
										'cUsuario', $cUsuario,
										"dAlta", Date("Y-m-d") ,
										"dModificacion", Date("Y-m-d") ,
										"cRoles", $cRoles,
										"bActivo", 1,
										"ncUsuario", $ncUsuario );
				// Redirecciona la siguiente accion
				$this->setInputData( $ncUsuario, $cUsuario );
			}
		// ELIMINAR_UN_USUARIO
		function trash( $ncUsuario = '')
			{
				if ( $ncUsuario != '' ||  $ncUsuario = getParam('ncUsuario') )
				{
					$this->oDatabase->update( 'stUsuario', "bActivo", 0, "dModificacion", Date("Y-m-d") , "WHERE", "ncUsuario", $ncUsuario );
				}
			}
		function untrash( $ncUsuario = '')
			{
				if ( $ncUsuario != '' ||  $ncUsuario = getParam('ncUsuario') )
				{
					$this->oDatabase->update( 'stUsuario', "bActivo", 1, "dModificacion", Date("Y-m-d") , "WHERE", "ncUsuario", $ncUsuario );
				}
			}
		function delete( $ncUsuario = '')
			{
				if ( $ncUsuario != '' ||  $ncUsuario = getParam('ncUsuario') )
				{
					$this->oDatabase->delete( 'stUsuario', "ncUsuario", $ncUsuario );
				}
			}

	// La validacion la hace la base directamente
	function loginDirecto ( $cUsuario, $cClave )
		{
			$this->oDatabase->user = $cUsuario;
			$this->oDatabase->password = $cClave;
			// Setea el Usuario con el que se conectara de ahora en adelante
			$this->oModule->oUserSession->login ( 1 , $cUsuario , $cClave );
			return $this->oDatabase->connect();
		}
	// Tiene que tener un usuario para conectarse a la base y valida contra una tabla de usuarios
	function loginIndirecto( $cUsuario, $cClave )
		{
			// Se conecta a la Base de Datos
			if ( $this->oDatabase->connect() == false )
			{
				addMessage ( "No se puede conectar a la Base de Datos" ) ;
				return false;
			}
			if ( $cUsuario =='' || $cClave =='') 
			{
				if ( $cUsuario =='' ) 
					addMessage ( "Debe ingresar un usuario" ) ;
				else
					addMessage ( "Debe ingresar una clave" ) ;
				return false;
			}
			// Busca si Existe el Usuario
			$cUsuario = strtolower($cUsuario);
			$cClave   = $this->hashPassword($cClave);
			$cSql = "SELECT *
									FROM stUsuario
									WHERE " . $this->oDatabase->dbLower('cUsuario')  . " = '$cUsuario'  ";
			$aDatos = $this->oDatabase->getArray($cSql);
			// Si no Existe el Usuario o la Clave es Incorrecta
			if ( ! is_array($aDatos) || $aDatos['ncUsuario'] == '')
				{
					addMessage ( "El usuario y/o clave no son validos" ) ;
					return false;
				}
			if ( $aDatos['cClave'] != $cClave )
				{
					addMessage ( "La clave y/o el usuario no son validos" ) ;
					return false;
				}
			if ( $aDatos['bBloqueada'] == true )
				{
					addMessage ( "La cuenta esta bloqueada" ) ;
					return false;
				}
			if (!$aDatos['bActivo'] )
				{
					addMessage ( "La cuenta esta dada de baja" ) ;
					return false;
				}
			$oHoy = new DateObject( Date("Y-m-d") );
			if ( CLAVE_EXPIRA_EN_DIAS && $oHoy->dateDiff('d', $aDatos['dUltimaClave'] ) > CLAVE_EXPIRA_EN_DIAS )
				{
					addMessage ( "La clave expiro por favor cambiela" ) ;
				}
			$ncUsuario 	= $aDatos['ncUsuario'];
			// Setea el Usuario con el que se conectara de ahora en adelante
			$this->oModule->oUserSession->login ( $ncUsuario , DB_USER , DB_PASSWORD, $aDatos['cRoles']  );
			$nqLogin = empty($aDatos['nqLogin']) ? 1 : $aDatos['nqLogin'] + 1;
			$this->oDatabase->update('stUsuario', "dUltimoLogin", date('Y-m-d') , "nqLogin", $nqLogin , "WHERE", "ncUsuario", $ncUsuario );
			return true;
		}
	// Tiene que tener un usuario para conectarse a la base y valida contra un store procedure, que le devuelve el usuario con el que debe conectarse
	function loginIndirectoSP ($cUsuario, $cClave )
		{
			// Verifica que esta conectado a la Base de Datos
			if ( $this->oDatabase->connect() == false )
			{
				addMessage ( "No se puede conectar a la Base de Datos" ) ;
				return false;
			}

			$cUsuario = strtolower($cUsuario);
			$cClave   = $this->hashPassword($cClave);
			$cUsuarioClave = $this->oDatabase->getData("gpValidarUsuario '$cUsuario' ,'$cClave'");
			if ( empty($cUsuarioClave) )
			{
				addMessage ( "El usuario y/o clave no son validos" );
				return false;
			}
			// Con el Usuario y Clave que Recibio del SP se vuelve a conectar
			$aConexion = explode( '|', $cUsuarioClave );
			$this->oDatabase->user     = $aConexion[0];
			$this->oDatabase->password = $aConexion[1];

			if ( $this->oDatabase->connect() == false )
			{
				addMessage ( "No se puede conectar a la Base de Datos en Modo Indirecto (SP)" ) ;
				return false;
			}

			return $this->loginIndirecto ($aConexion[0], $aConexion[1] );
		}
	function autoLogin()
		{
			$cLogin = $this->oModule->oUserSession->decrypt( $_COOKIE["cLogin"], CLAVE_HASH );
			list ( $cUsuario , $cClave ) = explode( "|", $cLogin );
			if ( $cClave && $cUsuario )
			{
				switch(DB_MODO)
				{
					case LOGIN_DIRECTO:
						$bOk = $this->loginDirecto( $cUsuario, $cClave );
						break;
					default:
					case LOGIN_INDIRECTO:
						$bOk = $this->loginIndirecto( $cUsuario, $cClave );
						break;
					case LOGIN_INDIRECTO_POR_SP:
						$bOk = $this->loginIndirectoSP( $cUsuario, $cClave );
						break;
				}
				if ( $bOk == true )
				{
					if ( !$this->oModule->getBack() ) 
					{
						$oModule =& loadModule(START_MODULE);
						$oModule->setRedirect( START_ACTION);
						//exit();
					}
				}
			}
			return $bOk;
		}

	// INGRESAR_AL_SISTEMA:
	function login()
		{
			// Si ya esta logeado => logout 
				$this->oModule->oUserSession->logout();
			// Convierte a variables los datos del Formulario asociado a la accion
			$oForm = $this->oModule->loadClass( 'login_frm' );
			$aDatos = $oForm->getFieldArray();
			switch(DB_MODO)
			{
				default:
				case LOGIN_INDIRECTO:
					$bOk = $this->loginIndirecto( $aDatos[cUsuario], $aDatos[cClave] );
					break;
				case LOGIN_DIRECTO:
					$bOk = $this->loginDirecto( $aDatos[cUsuario], $aDatos[cClave] );
					break;
				case LOGIN_INDIRECTO_POR_SP:
					$bOk = $this->loginIndirectoSP( $aDatos[cUsuario], $aDatos[cClave] );
					break;
			}
			if ( $bOk == true )
				{
					if ( $oForm->aFields['bAutoLogin']->getValue() )
					{
						$cLogin = $this->oModule->oUserSession->crypt( $aDatos[cUsuario] . '|'. $aDatos[cClave], CLAVE_HASH );
						setcookie( 'cLogin', $cLogin, time()+9999999 );
					} else
					{
						setcookie( 'cUsuario' );
						setcookie( 'cClave' );
						setcookie( 'cLogin' );
					}
					//$oModule =& loadModule(START_MODULE);
					//$oModule->setRedirect( START_ACTION);
					//$oModule->redirect();
					//exit();
				}
			// Si guardaba una url de antes del login
			/*
			$cUrlBack  = $this->oModule->getBack(VENTAN_SECUNDARIA);
			if ( $cUrlBack ) 
			{
				echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"";
				echo "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
				echo "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"es\" lang=\"es\">";
				echo "<head>";
				echo "<meta HTTP-EQUIV=Refresh CONTENT=\"0; url=" . $cUrlBack . "\"/>";
				echo "</head>";
			} else
			{}
			*/
		}
	// SALIR_DEL_SISTEMA
	function logout()
		{
			$this->oModule->oUserSession->logout();
			setcookie( 'cLogin', '', time()+9999999 );
			if ( FRAMEWORK_AJAX )
				$this->oModule->setRedirect( INGRESAR_AL_SISTEMA ); 
			else
				$this->oModule->setBack ( URL_ROOT );
			
			$this->oModule->redirect();
		}
	// CAMBIAR_CLAVE
	function changeKey()
		{
      // Convierte a variables los datos del Formulario asociado a la accion
      $oForm = $this->oModule->loadClass( 'Cambiar_clave_frm' );
      extract( $oForm->getFieldArray() );
			if ( $cClaveNueva1 != $cClaveNueva2 )
			{
				addMessage("La clave y la confirmacion no son iguales");
				return false;
			}
			// Valida si tien configurado un tamano minimo
			if ( CLAVE_MINIMO_TAMANO > 0 && strlen($cClaveNueva1) < CLAVE_MINIMO_TAMANO  )
			{
				addMessage("La clave es muy corta, debe tener como minimo " . CLAVE_MINIMO_TAMANO . " caracteres.");
				return false;
			}
			// Valida si tiene un minimo de letras y/o numeros
			if ( CLAVE_MIN_NUMEROS > 0 || CLAVE_MIN_LETRAS > 0 )
			{
				$nqNumeros = 0;
				$nqLetras  = 0;
				for( $nIndex = 0 ; $nIndex < strlen( $cClaveNueva1 ) ; $nIndex++ )
				{
					if ( is_numeric($cClaveNueva1[$nIndex]) ) $nqNumeros++;
					if ( is_string($cClaveNueva1[$nIndex]) ) $nqLetras++;
				}
				if ( $nqNumeros < CLAVE_MIN_NUMEROS )
				{
					addMessage("La clave debe tener al menos " . CLAVE_MIN_NUMEROS . " numero/s");
					return false;
				}
				if ( $nqLetras < CLAVE_MIN_LETRAS )
				{
					addMessage("La clave debe tener al menos " . CLAVE_MIN_LETRAS . " letra/s");
					return false;
				}
			}
			// Verifica si es correcta la clave actual
			$cClaveActual 		= $this->hashPassword( $cClaveActual );
			$bCorrecta 				= $this->oDatabase->getData("SELECT count(*) FROM stUsuario WHERE ncUsuario = $ncUsuario and cClave = '$cClaveActual'");
			if( $bCorrecta == 0 )
			{
				addMessage("La clave actual es incorrecta. Por favor reintente.");
				return false;
			}
			// Actualiza la nueva clave
			$cClaveNueva 	= $this->hashPassword($cClaveNueva1);
			$bExito 	= $this->oDatabase->update('stUsuario', "cClave", $cClaveNueva, "dUltimaClave", date('Y-m-d') ,"WHERE", "ncUsuario", $ncUsuario);
			if (!$bExito)
			{
				addMessage("No se pudo modificar la clave");
			}	else
			{
				addMessage("La clave fue modificada correctamente.");
			}
		}
	// RESETEO_DE_CLAVE
	function resetKey()
		{
			$ncUsuario = getParam( 'ncUsuario' );
			$cUsuario	= $this->oDatabase->getData("SELECT cUsuario FROM stUsuario WHERE ncUsuario = $ncUsuario");
			$cClaveNueva 	= $this->hashPassword($cUsuario);
			$bReturn = $this->oDatabase->update('stUsuario', 'cClave', $cClaveNueva, 'WHERE', 'ncUsuario', $ncUsuario );
			if ( $bReturn )
			{
				addMessage("La clave fue modificada correctamente.");
			}
		}

	function hashPassword ($cClave)
		{
			if ( CLAVE_CASE_SENSITIVE == false ) $cClave = strtolower($cClave);
			if ( CLAVE_SAVE_AS_HASH == true )  $cClave = sha1( $cClave );
			return $cClave;
    }
	}

?>
